﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net;
using System.Security.Claims;
using Urs.Core.Data;
using Urs.Core.Infrastructure;
using Urs.Services.Customers;
using Urs.Services.Security;

namespace Urs.Plugin.Misc.Api.Controllers
{
    public class ApiAuthorizeAttribute : TypeFilterAttribute
    {
        #region Fields

        private readonly bool _ignoreFilter;

        #endregion

        #region Ctor

        /// <summary>
        /// Create instance of the filter attribute
        /// </summary>
        /// <param name="ignore">Whether to ignore the execution of filter actions</param>
        public ApiAuthorizeAttribute(bool ignore = false) : base(typeof(ApiAuthorizeFilter))
        {
            this._ignoreFilter = ignore;
            this.Arguments = new object[] { ignore };
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets a value indicating whether to ignore the execution of filter actions
        /// </summary>
        public bool IgnoreFilter => _ignoreFilter;

        #endregion

        private class ApiAuthorizeFilter : IAuthorizationFilter
        {
            #region Fields

            private readonly bool _ignoreFilter;
            private readonly ICustomerService _customerService;

            #endregion

            #region Ctor

            public ApiAuthorizeFilter(bool ignoreFilter, ICustomerService customerService)
            {
                this._ignoreFilter = ignoreFilter;
                this._customerService = customerService;
            }

            #endregion

            public void OnAuthorization(AuthorizationFilterContext filterContext)
            {
                if (filterContext == null)
                    throw new ArgumentNullException(nameof(filterContext));

                if (filterContext.HttpContext.Request == null)
                    return;

                if (!DataSettingsManager.DatabaseIsInstalled)
                    return;

                var authorization = string.Empty;
                foreach (var item in filterContext.HttpContext.Request.Headers)
                {
                    if (item.Key == "Authorization" || item.Key == "authorization")
                    {
                        authorization = item.Value;
                        break;
                    }
                }
                if (!string.IsNullOrEmpty(authorization))
                {
                    try
                    {
                        var jwtSecurityToken = new JwtSecurityTokenHandler().ReadJwtToken(authorization);
                        if (jwtSecurityToken != null)
                        {
                            var claim = jwtSecurityToken.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
                            if (claim != null)
                            {
                                //将用户信息存放起来，供后续调用
                                filterContext.RouteData.Values.Add("guid", claim.Value);

                                Guid guid;
                                if (Guid.TryParse(claim.Value, out guid))
                                {
                                    var customer = _customerService.GetCustomerByGuid(guid);
                                    if (customer == null)
                                        filterContext.Result = new JsonResult(new { Code = 401, Content = "用户不存在" });
                                    if (!customer.Active || customer.Deleted)
                                        filterContext.Result = new JsonResult(new { Code = 401, Content = "用户被禁用" });
                                }
                                return;
                            }
                        }
                    }
                    catch
                    {
                    }
                }

                filterContext.Result = new JsonResult(new { Code = 401 });
            }
        }

    }
}
